<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Factorial</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 4.2.1">
<link rel="up" href="../factorials.html" title="Factorials and Binomial Coefficients">
<link rel="prev" href="../factorials.html" title="Factorials and Binomial Coefficients">
<link rel="next" href="sf_double_factorial.html" title="Double Factorial">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../factorials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../factorials.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="sf_double_factorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.factorials.sf_factorial"></a><a class="link" href="sf_factorial.html" title="Factorial">Factorial</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.factorials.sf_factorial.h0"></a>
        <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.synopsis"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.synopsis">Synopsis</a>
      </h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">factorials</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="identifier">unchecked_factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">max_factorial</span><span class="special">;</span>

<span class="special">}}</span> <span class="comment">// namespaces</span>
</pre>
<h5>
<a name="math_toolkit.factorials.sf_factorial.h1"></a>
        <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.description"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.description">Description</a>
      </h5>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top">
<p>
          The functions described below are templates where the template argument
          T CANNOT be deduced from the arguments passed to the function. Therefore
          if you write something like:
        </p>
<p>
          <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">factorial</span><span class="special">(</span><span class="number">2</span><span class="special">);</span></code>
        </p>
<p>
          You will get a (perhaps perplexing) compiler error, usually indicating
          that there is no such function to be found. Instead you need to specify
          the return type explicitly and write:
        </p>
<p>
          <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">factorial</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">2</span><span class="special">);</span></code>
        </p>
<p>
          So that the return type is known.
        </p>
<p>
          Furthermore, the template argument must be a real-valued type such as
          <code class="computeroutput"><span class="keyword">float</span></code> or <code class="computeroutput"><span class="keyword">double</span></code>
          and not an integer type - that would overflow far too easily for quite
          small values of parameter <code class="computeroutput"><span class="identifier">i</span></code>!
        </p>
<p>
          The source code <code class="computeroutput"><span class="keyword">static_assert</span></code>
          and comment just after the will be:
        </p>
<pre class="programlisting"><span class="keyword">static_assert</span><span class="special">(!</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">"Type T must not be an integral type"</span><span class="special">);</span>
<span class="comment">// factorial&lt;unsigned int&gt;(n) is not implemented</span>
<span class="comment">// because it would overflow integral type T for too small n</span>
<span class="comment">// to be useful. Use instead a floating-point type,</span>
<span class="comment">// and convert to an unsigned type if essential, for example:</span>
<span class="comment">// unsigned int nfac = static_cast&lt;unsigned int&gt;(factorial&lt;double&gt;(n));</span>
<span class="comment">// See factorial documentation for more detail.</span>
</pre>
</td></tr>
</table></div>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<span class="identifier">T</span> <span class="identifier">factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>
</pre>
<p>
        Returns <code class="literal">i!</code>.
      </p>
<p>
        The final <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can
        be used to control the behaviour of the function: how it handles errors,
        what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">policy
        documentation for more details</a>.
      </p>
<p>
        For <code class="literal">i &lt;= max_factorial&lt;T&gt;::value</code> this is implemented
        by table lookup, for larger values of <code class="literal">i</code>, this function
        is implemented in terms of <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a>.
      </p>
<p>
        If <code class="literal">i</code> is so large that the result can not be represented
        in type T, then calls <a class="link" href="../error_handling.html#math_toolkit.error_handling.overflow_error">overflow_error</a>.
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="identifier">unchecked_factorial</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span><span class="special">);</span>
</pre>
<p>
        Returns <code class="literal">i!</code>.
      </p>
<p>
        Internally this function performs table lookup of the result. Further it
        performs no range checking on the value of i: it is up to the caller to ensure
        that <code class="literal">i &lt;= max_factorial&lt;T&gt;::value</code>. This function
        is intended to be used inside inner loops that require fast table lookup
        of factorials, but requires care to ensure that argument <code class="literal">i</code>
        never grows too large.
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">max_factorial</span>
<span class="special">{</span>
   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">X</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
        This traits class defines the largest value that can be passed to <code class="literal">unchecked_factorial</code>.
        The member <code class="computeroutput"><span class="identifier">value</span></code> can be used
        where integral constant expressions are required: for example to define the
        size of further tables that depend on the factorials.
      </p>
<p>
        This function is <code class="computeroutput"><span class="keyword">constexpr</span></code> only
        if the compiler supports C++14 constexpr functions.
      </p>
<h5>
<a name="math_toolkit.factorials.sf_factorial.h2"></a>
        <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.accuracy"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.accuracy">Accuracy</a>
      </h5>
<p>
        For arguments smaller than <code class="computeroutput"><span class="identifier">max_factorial</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code> the result should be correctly rounded.
        For larger arguments the accuracy will be the same as for <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a>.
      </p>
<h5>
<a name="math_toolkit.factorials.sf_factorial.h3"></a>
        <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.testing"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.testing">Testing</a>
      </h5>
<p>
        Basic sanity checks and spot values to verify the data tables: the main tests
        for the <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a> function
        handle those cases already.
      </p>
<h5>
<a name="math_toolkit.factorials.sf_factorial.h4"></a>
        <span class="phrase"><a name="math_toolkit.factorials.sf_factorial.implementation"></a></span><a class="link" href="sf_factorial.html#math_toolkit.factorials.sf_factorial.implementation">Implementation</a>
      </h5>
<p>
        The factorial function is table driven for small arguments, and is implemented
        in terms of <a class="link" href="../sf_gamma/tgamma.html" title="Gamma">tgamma</a> for
        larger arguments.
      </p>
</div>
<div class="copyright-footer">Copyright © 2006-2021 Nikhar Agrawal, Anton Bikineev, Matthew Borland,
      Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert Holin, Bruno
      Lalande, John Maddock, Evan Miller, Jeremy Murphy, Matthew Pulver, Johan Råde,
      Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle
      Walker and Xiaogang Zhang<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../factorials.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../factorials.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="sf_double_factorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
